home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / db / esm-3.1 / esm-3 / usr / local / sm / src / serverlib / trans / commitTrans.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-05  |  7.2 KB  |  278 lines

  1. /*
  2.  *   $RCSfile: commitTrans.c,v $  
  3.  *   $Revision: 1.1.1.1 $  
  4.  *   $Date: 1996/05/04 21:56:02 $      
  5.  */ 
  6. /**********************************************************************
  7. * EXODUS Database Toolkit Software
  8. * Copyright (c) 1991 Computer Sciences Department, University of
  9. *                    Wisconsin -- Madison
  10. * All Rights Reserved.
  11. *
  12. * Permission to use, copy, modify and distribute this software and its
  13. * documentation is hereby granted, provided that both the copyright
  14. * notice and this permission notice appear in all copies of the
  15. * software, derivative works or modified versions, and any portions
  16. * thereof, and that both notices appear in supporting documentation.
  17. *
  18. * THE COMPUTER SCIENCES DEPARTMENT OF THE UNIVERSITY OF WISCONSIN --
  19. * MADISON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION.  
  20. * THE DEPARTMENT DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES
  21. * WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
  22. *
  23. * The EXODUS Project Group requests users of this software to return 
  24. * any improvements or extensions that they make to:
  25. *
  26. *   EXODUS Project Group 
  27. *     c/o David J. DeWitt and Michael J. Carey
  28. *   Computer Sciences Department
  29. *   University of Wisconsin -- Madison
  30. *   Madison, WI 53706
  31. *
  32. *     or exodus@cs.wisc.edu
  33. *
  34. * In addition, the EXODUS Project Group requests that users grant the 
  35. * Computer Sciences Department rights to redistribute these changes.
  36. **********************************************************************/
  37.  
  38. #include "sysdefs.h"
  39. #include "ess.h"
  40. #include "checking.h"
  41. #include "trace.h"
  42. #include "error.h"
  43. #include "list.h"
  44. #include "pool.h"
  45. #include "tid.h"
  46. #include "io.h"
  47. #include "lock.h"
  48. #include "object.h"
  49. #include "msgdefs.h"
  50. #include "thread.h"
  51. #include "semaphore.h"
  52. #include "link.h"
  53. #include "lsn.h"
  54. #include "latch.h"
  55. #include "bf.h"
  56. #include "volume.h"
  57. #include "trans.h"
  58. #include "openlog.h"
  59. #include "logrecs.h"
  60. #include "logaction.h"
  61. #include "bitvec.h"
  62. #include "adminmsg.h"
  63. #include "trans_intfuncs.h"
  64. #include "trans_extfuncs.h"
  65. #include "lm_extfuncs.h"
  66. #include "log_extfuncs.h"
  67. #include "msg_funcs.h"
  68. #include "io_extfuncs.h"
  69. #include "io_globals.h"
  70. #include "trans_globals.h"
  71. #include "thread_globals.h"
  72. #include "admin_globals.h"
  73.  
  74. /*
  75.  *    For write timing of log pages
  76.  */
  77. extern FOUR StatTotalTime_usec;
  78. extern FOUR StatPagesWritten;
  79. extern FOUR StatWriteCalls;
  80. extern FOUR    StatClientMsgs;
  81.  
  82.  void
  83. commitTrans (
  84.  
  85.     register TRANSREC    *transRec 
  86. )
  87. {
  88.  
  89.     DIRTYPAGELOGINFO    *dirtyInfo = DirtyPageLogInfo;
  90.     int                    numDirtyPages;
  91.     LOGRECORDINFO        recordInfo;
  92.     FORCEMARK            forceMark;
  93.     LIST                pendingBitmapList;
  94.  
  95.     TRPRINT(TR_TRANS, TR_LEVEL_2, ("tid:%x", GETTID(transRec)));
  96.  
  97.     if (PrintExtraStats && StatPagesWritten > 0) {
  98.         fprintf(sm_ErrorStream, "PreCommit write times: time=%d #pages=%d #writeCalls=%d clientMsgs=%d\n", StatTotalTime_usec/1000, StatPagesWritten, StatWriteCalls, StatClientMsgs);
  99.         StatPagesWritten = StatWriteCalls = StatClientMsgs = StatTotalTime_usec = 0;
  100.     }
  101.  
  102.     /*
  103.      *    Temporarily make the transaction active in order to log 
  104.      *    page deallocations.
  105.      */
  106.     transRec->transState = T_ACTIVE;
  107.  
  108.     initializeList(&(pendingBitmapList));    
  109.     
  110.     /* deallocate all temporary files and pages */
  111.     deallocTempFilesPages(transRec);
  112.  
  113.     /*
  114.      *    add all the pages in the all the files to be destroyed
  115.      *    to the list of pages to deallocate
  116.      */
  117.     if (transDeallocFilePages(transRec) != esmNOERROR) {
  118.         /* clean up dealloc info */
  119.         SM_ERROR(TYPE_CRASH, esmINTERNAL);
  120.     }
  121.  
  122.     /*
  123.      *    Log all pending page deallocations
  124.      */
  125.     if (logTransDeallocPages(transRec, &pendingBitmapList) != esmNOERROR) {
  126.         /* 
  127.          *     For now, just crash, but we should really clean things up
  128.          *    and abort the transaction.  Clean-up is complicated by
  129.          *    the bitmap and volume header pages which are pinned with
  130.          *    pending operations.
  131.          */
  132.         SM_ERROR(TYPE_CRASH, esmINTERNAL);
  133.     }
  134.  
  135.     /*
  136.      *    Restore transaction to the quiesced state
  137.      */
  138.     transRec->transState = T_QUIESCE;
  139.  
  140.     /*
  141.      *    If the transaction generated some log records, make sure they
  142.      *    are flushed.
  143.      */
  144.     if (transRec->logRecordCount > 0)    {
  145.  
  146.         /*  
  147.          *  Sync all unix file based volumes which were used by this
  148.          *  transaction.
  149.          */
  150.         if (io_SyncTransVolumes(&(transRec->volumeList)) != esmNOERROR) {
  151.             SM_ERROR(TYPE_CRASH, esmINTERNAL);
  152.         }
  153.  
  154.         /*
  155.          *    Make sure only one theead is using the global
  156.          *    variable DirtyPageLogInfo at a time.
  157.          */
  158.         if (waitSemaphore(&DirtyPageLogInfoSemaphore)) {
  159.             SM_ERROR(TYPE_FATAL, esmINTERNAL);
  160.         }
  161.  
  162.         /*
  163.          *    Fill an array of information for all pages dirtied by
  164.          *    this transaction since the last checkpoint.
  165.          */
  166.         numDirtyPages = listDirtyTransPages(transRec, dirtyInfo);
  167.         PRINT_PROGRESS(("logging %d pages as dirty since last checkpoint\n", numDirtyPages));
  168.  
  169.         /*
  170.          *    Generate a log record containing the dirty page info
  171.          */
  172.         recordInfo.action       = 0;
  173.         recordInfo.type         = LOG_REC_TYPE_DIRTYPAGELIST;
  174.         recordInfo.imageCount   = 1;
  175.         recordInfo.actionPid    = NULL;
  176.         recordInfo.actionLRC    = NULL;
  177.         recordInfo.imageSize[0] = numDirtyPages * sizeof(DIRTYPAGELOGINFO);
  178.         recordInfo.imageData[0] = (VOID *) dirtyInfo;
  179.         recordInfo.nextUndoLSN  = NULL_LSN;
  180.         recordInfo.flags          = REDO_ONLY;
  181.  
  182.         /*
  183.          *  write the record to the log
  184.          */
  185.         if ((forceMark = writeNonTransLogRecord(&recordInfo, NULL, NOFLAGS)) < 0)  {
  186.  
  187.             /*
  188.              *    abort the transaction
  189.              */
  190.              signalSemaphore(&DirtyPageLogInfoSemaphore); 
  191.              abortTrans(transRec, Active->errno);
  192.              reply(esmFAILURE, Active->errno, 1, TRUE);
  193.         }
  194.  
  195.         /*
  196.          *    Done with DirtyPageLogInfo
  197.          */
  198.         signalSemaphore(&DirtyPageLogInfoSemaphore); 
  199.  
  200.         /*
  201.          *    we must log the commit record and atomically change the
  202.          *    transaction state.
  203.          */
  204.         if (writeTransStateRecord(transRec, LOG_REC_TYPE_COMMIT, ZERO, T_COMMIT, TRUE) < esmNOERROR)    {
  205.  
  206.             /*
  207.              *    abort the transaction
  208.              */
  209.             abortTrans(transRec, Active->errno);
  210.             reply(esmFAILURE, Active->errno, 1, TRUE);
  211.         }
  212.  
  213.         /*
  214.          *    Perform all pending page deallocations
  215.          */
  216.         if (deallocTransPages(transRec, &pendingBitmapList) != esmNOERROR) {
  217.             SM_ERROR(TYPE_FATAL, esmINTERNAL);
  218.         }
  219.  
  220.     } else if (!transRec->loggingOn) {
  221.         /*
  222.          *    Since logging is turned off, we must write all dirty pages
  223.          *    since the checkpoint to disk.  This is most easily done
  224.          *    by calling listDirtyTransPages.
  225.          */
  226.         numDirtyPages = listDirtyTransPages(transRec, dirtyInfo);
  227.         PRINT_PROGRESS(("finished writing %d pages as dirty since last checkpoint\n", numDirtyPages));
  228.  
  229.     } else {
  230.         SM_ASSERT(LEVEL_3, LIST_EMPTY(&(transRec->clientDirtyList)));
  231.     }
  232.  
  233.     SM_ASSERT(LEVEL_3, LIST_EMPTY(&(transRec->fileDeallocList)));
  234.     SM_ASSERT(LEVEL_3, LIST_EMPTY(&(transRec->pageDeallocList)));
  235.     SM_ASSERT(LEVEL_3, LIST_EMPTY(&pendingBitmapList));
  236.  
  237.     /*
  238.      *    Make sure all bitmaps are consistent after any 
  239.      *    deallocation/allocation
  240.      */
  241.     SM_ASSERT(LEVEL_3, io_CheckAllVolumes() == esmNOERROR);
  242.  
  243.     /*
  244.      *    check to see if there are any log records
  245.      *    that are written for this transaction
  246.      */
  247.     if (transRec->lastLSN != 0)    {
  248.  
  249.         /*
  250.          *    take the record off the log queue
  251.          */
  252.         removeLogList(transRec);
  253.     }
  254.  
  255.     /*
  256.      *    free all the locks
  257.      */
  258.     unlockAll(transRec, esmTRANSCOMMITTED);
  259.  
  260.     /*
  261.      *    free the structures
  262.      */
  263.     freeTransVolRecs(transRec);
  264.  
  265.     /*
  266.      *    give back the transaction record
  267.      *  reset the state to T_INACTIVE
  268.      */
  269.     freeTransRec(transRec);
  270.  
  271.     TotalCommits++;
  272.  
  273.     /*
  274.      *    reply with success
  275.      */
  276.     reply(esmNOERROR, esmNOERROR, 1, TRUE);
  277. }
  278.